      /*
      ------分数注意事项-----
      本次测试满分为100(最多100分), 有4道加分题; 答案不够完整或者有错误当题0分处理;

      ------分数处理-----
      (0-60]: 不及格, 处理: 提供第二份不同试卷晚自习的时候重新考试, 并在第二天晚自习时间单独进行测试题提问(大部分都回答不上则采用手抄试卷方案);

      (60-75]: 良良, 处理: 晚自习时间单独进行测试题提问(大部分都回答不上则采用手抄试卷方案);

      (75-90]: 良好, 处理: 放你一马, 好好复习;

      (90-100]: 优秀, 处理: 好好好, 继续保持;
      */
      // 1.JS延迟加载的方式有哪些？（5）

      // 1.addEventListener("onload",function(){}) 这种方法是对页面的元素、标签、资源加载完后再进行加载js，避免元素资源加载过慢而导致js出错，
      // 一般是运用在写代码时script脚本写在页面标签之前
      // 2.setTimeout(function(){},time) 这个为延时定时器，在time（单位：ms/毫秒）时间后才执行回调函数function内的代码，只执行一次
      // 3.setInterval（function(){},time) 这个为间歇定时器，在每隔time（单位：ms/毫秒）时间后再执行回调函数function内的代码，
      // 这种方式可执行多次直至定时器关闭，当这个定时器规定只执行一次的时候，就能够达到js的延迟加载

      // 2.前端 JavaScript 中的 ECMAScript、DOM、BOM 的含义；（5）
      // ECMAScript ECMAScript是ECMA组织制定的一套规则，使用来规定在js中代码的标准
      // DOM 全称文档对象模型（document object model），在一个html页面中有许多元素，每个元素可以称为一个节点，html可以看成是一个DOM树，
      // 当我需要查找到某一个节点时，就是根据当前的节点位于DOM树的位置去获取，获取后可以对节点绑定事件
      // BOM 全称浏览器对象模型（document object model），BOM是附属于浏览器的内容，不同于DOM，DOM是对html页面的元素进行处理，
      // 而BOM是对浏览器进行处理，例如浏览器上的导航栏、工具栏等

      // 4.如何进行数据类型的判断？（5）

      // 1.typeof + 数据
      //   "typeof+数据" 返回的是一个字符串，对于基本数据类型大部分可以准确返回其类型（除了null，返回的是Object），对于对象、数组类型一律返回Object
      //     方法函数返回function
      // 2.A instanceof B
      //   "A instanceof B" 使用来判断数据A的数据类型是否与B相同，返回的是一个布尔值，相同返回的是true，不相同则返回false
      //     这里的A为数据，B为数据类型的构造函数，但是数组 instanceof Object返回的是true
      // 3.Object.prototype.toString.call(数据)
      //   "Object.prototype.toString.call(数据)" 是根据数据调用对象中的原型方法去判断该数据的类型，返回的是一个[Object 数据类型]

      // 5.null 和 undefined 的区别？什么时候会得到 undefined？（5）
      // undefined是对于变量未定义，而null是对变量的指针指向空
      // 1.当声明变量后未对其赋值，计算机会自动将其赋值为undefined
      // 2.当function(){}中没有写明返回值的时候，默认返回undefined
      // 3.当访问未声明的变量时，会报错“xxx is not defined”

      // 6.如何理解 null == undefined 返回 true，null === undefined 返回 false？（5）
      // "=="是对于判断数据的值是否相等，在用到比较运算符的时候，会将数据类型隐式转换成数字类型，这里的null和undefined都转化为数字0，所以"null==undefined"返回true
      // "==="是对于判断数据的值和类型时候相等，在用到"==="的时候，只有两边的数据一模一样的时候才会返回true，所以"null===undefined"返回false

      // 7.使用 continue 或 break 终止循环时，两种方式的区别是？（5）

      // continue 是对于当前的循环进行中断，然后进入到下一次的循环中
      // break 是对于整个循环的中断，break后直接跳出整个循环

      // 8.如何判断字符串内是否包含指定字符？（5）
      // 1.字符串1.indexOf("字符串2")
      // 使用"字符串1.indexOf("字符串1")" 是判断字符串1是否含有字符串2的内容，有则返回字符串2在字符串1出现的开始下标，没有则返回-1
      // 2.字符串1.lastIndexOf("字符串2")
      // 使用"字符串1.indexOf("字符串1")"在判断字符串从头到尾的是否包含另一个字符串的时候用法与"字符串1.indexOf("字符串1")"一样
      let str1 = "123456789";
      let str2 = "0";
      let str3 = "5";
      console.log(str1.indexOf(str2)); //返回-1，
      console.log(str1.indexOf(str3)); //返回4

      // 9.请尽量列举出数组的方法，并且注明哪些方法会修改原数组，哪些不会；（5）
      // concat() 数组的拼接，返回一个新数组，不会修改原数组
      // join("分隔符") 数组转字符串,字符串之间会用"分隔符分开"
      // splice(a,b,c) 将数组进行修改/添加/删除操作，会修改原数组
      // slice(startIndex，endIndex) 将数组截取从开始下标截取到结束下标（如果没有默认截取到最后），返回新数组，不会修改原数组
      // push\pop\shift\unshift 对数组进行（从数组最后添加/从数组最后删除/从数组开头删除/从数组开头添加），会修改原数组
      // forEach(function(item,index,arr){}) 对数组遍历,没有返回值，不会修改原数组
      // map(function(item,index,arr){}) 对数组遍历后，可以对数组进行操作，可以返回新数组，不会修改原数组
      // includes("数据") 对数组进行遍历，查找数组中是否包含"数据",不会修改原数组
      // every(function(item,index,arr){}) 对数组进行遍历，对数组每一个元素进行判断是否符合条件，都符合返回true，有一个不符合返回false，不会修改原数组
      // some(function(item,index,arr){}) 对数组进行遍历，对数组每一个元素进行判断是否符合条件，有一个符合返回true，都不符合返回false，不会修改原数组
      // reduce(function(total,item,index){},init) 对数组进行遍历，可以对数组的每一个元素操作后加入到total中来实现累加器的效果，不会修改原数组
      // sort(function(a,b){}) 对数组按照一定的规则进行排序，不会修改原数组

      // 10. 请写出下面语句的输出结果：（5）
      // let bar = true, number = 0;
      // console.log(bar + 0);        1
      // console.log(bar + "xyz");    truexyz
      // console.log(bar + true);     2
      // console.log(+true);          1
      // console.log(!'bluej');       false
      // console.log(number++);       0
      // console.log(++number);       2
      // console.log(number);         2

      // 11. 根据用户输入时间实现倒计时，输入时间格式错误时要有错误提示（5）
      // window.prompt("请输入目标时间");
      let button11 = document.querySelector("button");
      button11.addEventListener("click", function () {
        let t = new Date(
          window.prompt("请输入目标时间（格式为：xxxx xx xx xx:xx:xx）")
        ).getTime(); //目标时间的时间戳
        if (typeof time != "number") {
          alert("请输入正确时间格式");
        } else {
          daojishi(t);
        }
      });
      let q11 = document.querySelector(".q11");
      function daojishi(t) {
        t = t;
        let timer = setInterval(function () {
          let nowTime = new Date().getTime(); //当前时间的时间戳
          let diff = Math.floor(t - nowTime) / 1000; //相差时间秒数
          if (diff < 0) {
            q11.innerHTML = "时间已过";
            return;
          } else {
            let second =
              Math.floor(diff % 60) < 10
                ? "0" + Math.floor(diff % 60)
                : Math.floor(diff % 60);
            let min =
              Math.floor(diff / 60) % 60 < 10
                ? "0" + (Math.floor(diff / 60) % 60)
                : Math.floor(diff / 60) % 60;
            let hour =
              Math.floor(diff / 60 / 60) % 24 < 10
                ? "0" + (Math.floor(diff / 60 / 60) % 24)
                : Math.floor(diff / 60 / 60) % 24;
            let date =
              Math.floor(diff / 60 / 60 / 24) < 10
                ? "0" + Math.floor(diff / 60 / 60 / 24)
                : Math.floor(diff / 60 / 60 / 24);
            // console.log(
            //   `离目标时间还有：${date}天${hour}小时${min}分钟${second}秒`
            // );
            q11.innerHTML = `离目标时间还有：${date}天${hour}小时${min}分钟${second}秒`;
          }
        }, 1000);
      }
      // 12.输出从小到大排序好的五个不重复的随机"素数",范围[10-58)；（10）
      // 质数也叫素数是指在大于1的自然数中，除了1和它本身以外不再有其他因数的自然数，不能被任何整数整除的数。

      function getRandom(m, n) {
        return Math.floor(Math.random() * (n - m) + m);
      }
      function findNum(n) {
        for (let i = 1; i <= 5; i++) {
          let num = getRandom(10, 58); //获取[10,58)的随机数
        }
      }
      findNum(5);
      // 13.把下面数组成员排序打乱；（5）
      let arr13 = [10, 20, 30, 40, 50, 60];
      let newArr2 = []; // 打乱之后的数组
      function getRandom1(arr) {
        return Math.floor(Math.random() * arr.length);
      }
      function mix(arr1, arr2) {
        let oldLength = arr1.length; //记录原始数组长度
        for (let i = 0; i < oldLength; i++) {
          let num = getRandom1(arr1); //随机获取下标,根据数组长度变化
          arr2.push(arr1[num]);
          arr1.splice(num, 1);
        }
        console.log(arr2);
      }
      mix(arr13, newArr2);

      // 14. 将多个数组进行去重合并；（10）
      let arr140 = [1, 2, 3],
        arr141 = [2, 3, 4, 5];
      function quchong(arr1, arr2) {
        let newArr = arr1.concat(arr2);
        console.log(newArr);
        let newArr2 = [];
        for (let i = 0; i < newArr.length; i++) {
          if (
            newArr2.every(function (item, index) {
              return item != newArr[i];
            })
          ) {
            newArr2.push(newArr[i]);
          }
        }
        console.log(newArr2);
      }
      quchong(arr140, arr141);

      // 15. 找出数组 arr=[1, 2, 3, "a", 4, "a", 2, 4, "a"] 中重复出现过的元素,并用数组将重复元素装起来输出,并且统计每个元素出现的次数（10）

      let arr15 = [1, 2, 3, "a", 4, "a", 2, 4, "a"];
      let obj = {};
      arr15.forEach(function (item, index, arr15) {
        if (obj[item]) {
          obj[item]++;
        } else {
          obj[item] = 1;
        }
        if (index === arr15.length - 1) {
          for (const k in obj) {
            if (obj[k] === 1) delete obj[k];
          }
          console.log(obj);
        }
      });

      // 16. 找出数组中年龄小于18岁的女生的信息重新组成新的数组,并且将她们count变为现有的平方（10）
      let arr16 = [
        {
          name: "111",
          sex: "boy",
          age: 18,
          count: 20,
        },
        {
          name: "222",
          sex: "girl",
          age: 17,
          count: 30,
        },
        {
          name: "333",
          sex: "boy",
          age: 16,
          count: 40,
        },
        {
          name: "444",
          sex: "girl",
          age: 15,
          count: 50,
        },
        {
          name: "555",
          sex: "boy",
          age: 20,
          count: 60,
        },
        {
          name: "666",
          sex: "girl",
          age: 13,
          count: 70,
        },
        {
          name: "777",
          sex: "boy",
          age: 14,
          count: 80,
        },
      ];
      let newArr16 = arr16
        .filter(function (item, index) {
          return item.age < 18;
        })
        .map(function (item) {
          item.count *= item.count;
          return item;
        });
      console.log(newArr16);

      // 17. 实现一个深克隆函数 (加分题 5)
      let obj17 = {
        a: 1,
        b: [1, 2, 3],
        c: { a: 1 },
        d: function () {
          console.log("123");
        },
      };
      let newObj17 = {};
      function cloneDeep(obj) {
        let res;
        if (Object.prototype.toString.call(obj).slice(8, -1) == "Array") {
          res = [];
        } else if (
          Object.prototype.toString.call(obj).slice(8, -1) == "Object"
        ) {
          res = {};
        }
        for (const k in obj) {
          if (obj[k] instanceof Object) {
            res[k] = cloneDeep(obj[k]);
          } else {
            res[k] = obj[k];
          }
        }
        return res;
      }
      newObj17 = cloneDeep(obj17);
      console.log(newObj17);

      // 18. 实现一个数组的reduce方法 (加分题 5)
      // 实现数组值的累加
      let arr18 = [1, 2, 3, 4, 5, 6];
      let sum = arr18.reduce(function (total, item, index) {
        return (total += item);
      }, 0);
      console.log(sum);

      // 19. 写出强制转换的方法有哪些 (加分题 5)
      // Number() 强制转换成number类型
      // String() 强制转换成string类型
      // toString() 只有在对象下可以使用
      // Boolean() 强制转换成布尔类型

      // 20. 如何判断一个对象是否为空对象的3种方法 (加分题 5)